﻿#define _CRT_SECURE_NO_WARNINGS 1
// 原题连接：https://ac.nowcoder.com/acm/problem/235954
/*
题目描述：
链接：https://ac.nowcoder.com/acm/problem/235954
来源：牛客网

题目描述
Michael喜欢滑雪， 因为滑雪很刺激。可是为了获得速度，滑坡必须向下倾斜。Michael想知道一个
𝑛
×
𝑚
n×m 的区域中最长的滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子 1 2 3 4 5

16 17 18 19 6

15 24 25 20 7

14 23 22 21 8

13 12 11 10 9

Michael可以从某个点滑向上下左右相邻四个点之一，当且仅当下一个点的高度小于当前点的高度。在上面的例子中，一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。你能帮帮他吗。

输入描述:
第一行包含两个整数
𝑛
,
𝑚
(
1
≤
𝑛
,
𝑚
≤
100
)
n,m(1≤n,m≤100) ，表示区域的大小。

接下来
𝑛
n 行，每行
𝑚
m 个正整数，分别表示每个位置的高度
ℎ
(
1
≤
ℎ
≤
10000
)
h(1≤h≤10000) 。


输出描述:
输出一行一个整数，代表区域中最长滑坡的长度。
*/

#include <iostream>
#include <cstring>
using namespace std;
const int N = 110;
int grid[N][N];
int memo[N][N];
int dx[4] = { -1, 1, 0, 0 }, dy[4] = { 0, 0, 1, -1 };
int n = 0, m = 0;
int dfs(int a, int b) {
    int& ret = memo[a][b];
    if (ret != -1) {
        return ret;
    }
    ret = 1;
    for (int k = 0; k < 4; k++) {
        int x = a + dx[k], y = b + dy[k];
        if (x >= 0 && x < n && y >= 0 && y < m && grid[a][b] > grid[x][y]) {
            ret = max(ret, dfs(x, y) + 1);
        }
    }
    return ret;
}
int main() {
    memset(memo, -1, sizeof memo);
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            scanf("%d", &grid[i][j]);
        }
    }
    int ret = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            ret = max(ret, dfs(i, j));
        }
    }
    printf("%d\n", ret);
    return 0;
}